﻿//------------------------------------------------------------------------------------------------- 
// <copyright file="SetupProviderManager.cs" company="Microsoft">
// Microsoft Public License (Ms-PL) - https://smartsetup.codeplex.com/license
// </copyright>
// <author>Steven Shan</author>
//-------------------------------------------------------------------------------------------------

namespace Microsoft.STEVSHAN.SmartSetup.Engine
{
    using Microsoft.STEVSHAN.SmartSetup.Common;
    using Microsoft.STEVSHAN.SmartSetup.Providers;
    using System;
    using System.Collections.Generic;

    internal sealed class SetupProviderManager : ISetupProviderManager
    {
        private IList<ISetupProvider> _providerList;

        public SetupProviderManager()
        {
            this._providerList = new List<ISetupProvider>();
        }

        public int AppendProvider(ISetupProvider provider)
        {
            this._providerList.Add(provider);
            return this._providerList.Count;
        }

        public bool CanHandle(string path)
        {
            foreach (var provider in this._providerList)
            {
                if (provider.CanHandle(path))
                {
                    return true;
                }
            }

            return false;
        }

        public bool CanHandle(System.IO.Stream stream)
        {
            foreach (var provider in this._providerList)
            {
                if (provider.CanHandle(stream))
                {
                    return true;
                }
            }

            return false;
        }

        public ISetupItem CreateSetupItem(string path)
        {
            ISetupItem setupItem;

            if (!this.TryCreateSetupItem(path, out setupItem))
            {
                throw new Exception();
            }

            return setupItem;
        }

        public ISetupItem CreateSetupItem(System.IO.Stream stream)
        {
            ISetupItem setupItem;

            if (!this.TryCreateSetupItem(stream, out setupItem))
            {
                throw new Exception();
            }

            return setupItem;
        }

        public IEnumerator<ISetupProvider> GetEnumerator()
        {
            return this._providerList.GetEnumerator();
        }

        public int IndexOfProvider(ISetupProvider provider)
        {
            return this._providerList.IndexOf(provider);
        }

        public int InsertProvider(ISetupProvider provider, int index)
        {
            this._providerList.Insert(index, provider);
            return index;
        }

        public int RemoveProvider(ISetupProvider provider)
        {
            int index = this._providerList.IndexOf(provider);

            if ((index < 0) || (index >= this._providerList.Count))
            {
                return -1;
            }

            this._providerList.RemoveAt(index);
            return index;
        }

        public int RemoveProviderAt(int index)
        {
            this._providerList.RemoveAt(index);
            return index;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this._providerList.GetEnumerator();
        }
        
        public bool TryCreateSetupItem(string path, out ISetupItem setupItem)
        {
            foreach (var provider in this._providerList)
            {
                if (provider.TryCreateSetupItem(path, out setupItem))
                {
                    return true;
                }
            }

            setupItem = null;
            return false;
        }

        public bool TryCreateSetupItem(System.IO.Stream stream, out ISetupItem setupItem)
        {
            foreach (var provider in this._providerList)
            {
                if (provider.TryCreateSetupItem(stream, out setupItem))
                {
                    return true;
                }
            }

            setupItem = null;
            return false;
        }
    }
}